package cn.itcast.nems.manager.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.CaseFormat;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 功能描述:
 * request request转实体entity工具类
 * 从HttpServletRequest对象中获取请求体并将其转换为实体类
 * MyEntity myEntity = RequestToEntityConverter.convert(request, MyEntity.class);
 *
 * @author 陈早庆
 * @update:[变更日期2023-12-14][陈早庆][变更描述]
 * @since 2023-12-14
 */
public class RequestToEntityConverter {
    private static final ObjectMapper objectMapper = new ObjectMapper();

    public static Object convert(HttpServletRequest request, Class<?> beanClass) {
        Object obj = null;
        try {
            //创建一个新的无指向实体反射
            obj = beanClass.newInstance();
            //获取该类的所有字段信息
            Field[] fields = beanClass.getDeclaredFields();
            Class<?> fieldType;
            String fieldName;
            for (Field field : fields) {
                field.setAccessible(true);
                //获取当前循环的字段名称
                fieldName = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName());
                if (Modifier.isFinal(field.getModifiers())) {
                    continue;
                }
                //如果再request中不存在就赋值为null
                if (StringUtils.isEmpty(request.getParameter(fieldName))) {
                    field.set(obj, null);
                    continue;
                }
                //获取当前字段的类型
                fieldType = field.getType();
                //根据当前类型判断强转并通过当前字段名取值并赋值到新的类中
                if (fieldType == int.class || fieldType == Integer.class) {
                    field.set(obj, Integer.valueOf(request.getParameter(fieldName)));
                } else if (fieldType == long.class || fieldType == Long.class) {
                    field.set(obj, Long.valueOf(request.getParameter(fieldName)));
                } else if (fieldType == float.class || fieldType == Float.class) {
                    field.set(obj, Float.valueOf(request.getParameter(fieldName)));
                } else if (fieldType == double.class || fieldType == Double.class) {
                    field.set(obj, Double.valueOf(request.getParameter(fieldName)));
                } else if (fieldType == boolean.class || fieldType == Boolean.class) {
                    field.set(obj, Boolean.valueOf(request.getParameter(fieldName)));
                } else if (fieldType == short.class || fieldType == Short.class) {
                    field.set(obj, Short.valueOf(request.getParameter(fieldName)));
                } else if (fieldType == BigDecimal.class) {
                    field.set(obj, BigDecimal.valueOf(Long.parseLong(request.getParameter(fieldName))));
                } else if (fieldType == Date.class) {
                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
                    field.set(obj, formatter.parse(request.getParameter(fieldName)));
                } else if (fieldType == LocalDate.class) {
                    DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    field.set(obj, LocalDate.parse(request.getParameter(fieldName), df));
                } else if (fieldType == String.class) {
                    field.set(obj, request.getParameter(fieldName));
                } else if (fieldType == Set.class) {
                    field.set(obj, new HashSet(Arrays.asList(request.getParameter(fieldName).split(","))));
                } else if (fieldType == List.class) {
                    field.set(obj, Arrays.asList(request.getParameter(fieldName).split(",")));
                }else {
                    //如果不在常见的基本类型就讲数据赋值为null
                    field.set(obj, null);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }

}
